-- 2022-7-28

--[[
    table.unpack 从一个表中返回多个值
    
    unpack 函数的重要用途之一体现在泛型调用机制中。
    泛型调用机制允许我们动态的调用具有任意参数的任意函数

    也可以显示的返回元素的范围
]]

--[[正确的尾调用
    Lua语言是支持尾调用消除的，这意味着Lua语言可以正确的尾递归
    尾调用是被当作函数调用使用的跳转。
    当一个函数的最后一个动作是调用另一个函数而没有再进行其他工作时，就形成了尾调用
    例如    functiom f(x) x = x + 1; return g(x) end
    当函数f调用完函数g之后，f不需要进行其他的工作。
    这样被调用的函数执行结束后，程序就不需要返回最初的调用者
    因此在尾调用之后，程序不需要在调用栈中保存关于调用函数的信息
    当g返回时，程序的执行路径直接返回到调用f的为位置
    这种不占用任何额外栈空间的的实现称为尾调用消除
    由于尾调用不会使用栈空间，所以一个程序在能够嵌套的尾调用的数量是无限的
    关于尾调用消除的一个重点是如何判断一个调用是尾调用
        例如
            function f(x) g(x) end -- 这不是尾调用
            return g(x) + 1 -- 必须进行加法
            return x or g(x) -- 必须把返回值限定为1个
            return (g(x)) -- 必须把返回值限定为1个
    在Lua语言中只有形如return func(args)的调用才是尾调用
    不过由于Lua语言会在调用前对func及其函数参数求值，所以func及其参数都可以是复杂的表达式
        例如 
            return x[i].foo(x[j] + a*b , i + j)
]]

---[[
    --打印数组元素
    a = {1,2,3,4,5}
    for i=1, #a do
        print(a[i])
    end

    print("----")
    --打乱数组
    function RangeSort(a)
        local tb = {}
        len = #a
        for i=1, len do
            local index = math.random(1,len - i + 1)
            x = table.remove(a,index)
            table.insert(tb,x)
        end
        return tb
    end
    tb = RangeSort(a)
    for i=1, #tb do
        print(tb[i])
    end

    print("---")
--]]